package com.sengled.cloud.biz.union.mgt.service.sys.impl;

import com.sengled.cloud.biz.union.mgt.common.CommonConstant;
import com.sengled.cloud.biz.union.mgt.common.PageUtil;
import com.sengled.cloud.biz.union.mgt.common.SysConstants;
import com.sengled.cloud.biz.union.mgt.common.util.SessionUtil;
import com.sengled.cloud.biz.union.mgt.dao.sys.*;
import com.sengled.cloud.biz.union.mgt.model.dto.UnionUser;
import com.sengled.cloud.biz.union.mgt.model.enums.RoleTypeEnum;
import com.sengled.cloud.biz.union.mgt.model.po.*;
import com.sengled.cloud.biz.union.mgt.model.request.GetRoleListRequest;
import com.sengled.cloud.biz.union.mgt.model.request.SaveOrUpdateRoleRequest;
import com.sengled.cloud.biz.union.mgt.model.response.*;
import com.sengled.cloud.biz.union.mgt.model.vo.*;
import com.sengled.cloud.biz.union.mgt.service.sys.IRoleManageService;
import com.sengled.cloud.biz.union.mgt.service.sys.IUserService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.session.ExpiringSession;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by chenshuai on 2017/10/10.
 */
@Service("roleManageServiceImpl")
@Transactional(value="txManager",rollbackFor = {Exception.class}, propagation = Propagation.REQUIRED)
public class RoleManageServiceImpl implements IRoleManageService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RoleDao roleDao;
    @Autowired
    private ModuleDao moduleDao;
    @Autowired
    private RoleModulePermissionDao roleModulePermissionDao;
    @Autowired
    private UserAccountDao userAccountDao;
    @Autowired
    private AccountRoleDao accountRoleDao;
    @Autowired
    private PermissionDao permissionDao;
    @Autowired
    private ShopAccountDao shopAccountDao;
    @Autowired
    private CurrentShopDao currentShopDao;
    @Autowired
    private UserAcctShopAcctDao userAcctShopAcctDao;
    @Autowired
    private ShopAccountModuleDao shopAccountModuleDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private IUserService userService;
    @Autowired
    private UserRoleDao userRoleDao;
    @Resource
    private FindByIndexNameSessionRepository<ExpiringSession> sessionRepository;

    @Override
    public ResponseMessage<QueryRoleWithPage> getRoleList(GetRoleListRequest getRoleListRequest,Long accountId) {
        ResponseMessage<QueryRoleWithPage> rm = new ResponseMessage<QueryRoleWithPage>();
        try {
        //通过登录用户查询对应companyId，查询的角色的companyId与用户companyId相同
        UserAccount userAccount = userAccountDao.selectByPrimaryKey(accountId);
        Long companyId;
        if(userAccount != null && userAccount.getCompanyId()!=null){
            companyId = userAccount.getCompanyId();

            Role role = new Role();
            role.setCompanyId(companyId);
            if(getRoleListRequest != null){
                role.setRoleCode(getRoleListRequest.getRoleCode());
                role.setRoleName(getRoleListRequest.getRoleName());
                role.setRoleType(getRoleListRequest.getRoleType());
            }

                /*int currentPage = 1;
                if(getRoleListRequest.getCurrentPage() != null){
                    currentPage = getRoleListRequest.getCurrentPage();
                }*/
                int rowCount = roleDao.queryTotalRole(role);
                if(rowCount > 0){
                    PageUtil pageUtil = new PageUtil(getRoleListRequest.getCurrentPage(), CommonConstant.PageConstant.PAGE_SIZE,rowCount);
                    //pageUtil.setPage(currentPage);
                    List<RoleWithRoleType> roles = roleDao.listRole(role,pageUtil);
                    if(roles != null && roles.size() > 0){
                        roles.forEach(r -> {
                            if(r != null){
                                if(r.getRoleType() == RoleTypeEnum.ROLE_TYPE_FORMAL.getKey()){
                                    r.setRoleTypeName(RoleTypeEnum.ROLE_TYPE_FORMAL.getValue());
                                }else if(r.getRoleType() == RoleTypeEnum.ROLE_TYPE_TEMPLATE.getKey()){
                                    r.setRoleTypeName(RoleTypeEnum.ROLE_TYPE_TEMPLATE.getValue());
                                }
                            }
                        });
                    }

                    QueryRoleWithPage qrwp = new QueryRoleWithPage();
                    qrwp.setPage(pageUtil);
                    qrwp.setRoles(roles);
                    rm.setData(qrwp);
                }

            }

        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            rm.buildSystemErrorMessage();
            logger.debug(e.getMessage(), e);
        }
        return rm;
    }

    @Override
    public ResponseMessage<List<ModulePermissions>> getModulePermissions() {
        ResponseMessage<List<ModulePermissions>> rm = new ResponseMessage<List<ModulePermissions>>();
        try {
            List<ModulePermissions> modulePermissionses = this.getModulePermissions(0L);
            modulePermissionses = getIteratModulePermissions(modulePermissionses);
            rm.setData(modulePermissionses);

        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            rm.buildSystemErrorMessage();
            logger.debug(e.getMessage(), e);
        }
        return rm;
    }

    private List<ModulePermissions> getModulePermissions(Long id){
        List<ModulePermissions> modulePermissionses = moduleDao.selectByParentId(id);
        return modulePermissionses;
    }

    private List<ModulePermissionsWithChecked> getModuleWithChecked(Long id){
        List<ModulePermissionsWithChecked> modulePermissionsWithCheckedList = moduleDao.selectByParentIdWithChecked(id);
        return modulePermissionsWithCheckedList;
    }

    private List<ModulePermissions> getIteratModulePermissions(List<ModulePermissions> modulePermissionses){
        try {
            if(modulePermissionses != null && modulePermissionses.size() > 0){
                modulePermissionses.forEach(modulePermission -> {
                    Long parentId = modulePermission.getId();
                    List<ModulePermissions> childModules = this.getModulePermissions(parentId);
                    if(childModules != null && childModules.size() > 0){
                        modulePermission.setChildModules(childModules);
                        this.getIteratModulePermissions(childModules);
                    }
                });
            }
            return modulePermissionses;
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
            return null;
        }
    }

    private List<ModulePermissionsWithChecked> getIteratModulePermissionsWithChecked(List<ModulePermissionsWithChecked> modulePermissionsWithCheckedList,Long id){

        try {
            if(modulePermissionsWithCheckedList != null && modulePermissionsWithCheckedList.size() > 0){

                modulePermissionsWithCheckedList.forEach(l -> {
                    List<Long> checkedPermission = roleModulePermissionDao.selectByRoleAndModuleKey(id,l.getId());
                    if(CollectionUtils.isNotEmpty(checkedPermission)){
                        l.setChecked(true);
                    }
                });

                modulePermissionsWithCheckedList.forEach(modulePermissionsWithChecked -> {
                    Long parentId = modulePermissionsWithChecked.getId();
                    List<PermissionWithChecked> permissionWithCheckeds = modulePermissionsWithChecked.getPermissionWithCheckedList();
                    if(permissionWithCheckeds != null && permissionWithCheckeds.size() > 0){
                        List<Long> checkedPermission = roleModulePermissionDao.selectByRoleAndModuleKey(id,parentId);
                        Map<Long,Long> checkedPermissionMap = new HashMap<Long, Long>();
                        checkedPermission.forEach(s -> {
                            checkedPermissionMap.put(s,s);
                        });
                        permissionWithCheckeds.forEach(p -> {
                            Long l = p.getId();
                            if(checkedPermissionMap.containsKey(l)){
                                p.setChecked(true);
                            }
                        });
                    }
                    List<ModulePermissionsWithChecked> childModules = this.getModuleWithChecked(parentId);
                    if(childModules != null && childModules.size() > 0){
                        modulePermissionsWithChecked.setChildModules(childModules);
                        this.getIteratModulePermissionsWithChecked(childModules,id);
                    }
                });
            }
            return modulePermissionsWithCheckedList;
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
            return null;
        }
    }

    @Override
    public ResponseMessage<RoleEditResponse> getModulePermissionsWithChecked(Long id) {
        ResponseMessage<RoleEditResponse> rm = new ResponseMessage<RoleEditResponse>();
        RoleEditResponse roleEditResponse =  new RoleEditResponse();
        Role role = roleDao.selectByPrimaryKey(id);
        if(role != null){
            roleEditResponse.setRole(role);
        }
        try {
            List<ModulePermissionsWithChecked> modulePermissionsWithCheckedList = this.getModuleWithChecked(0L);
            modulePermissionsWithCheckedList = getIteratModulePermissionsWithChecked(modulePermissionsWithCheckedList,id);
            //--------------------------------------没办法的补丁start------------------------------------------------
            Map<Long,Integer> pcMap = new HashMap();
            pcMap.put(1L,5);
            pcMap.put(7L,3);
            pcMap.put(23L,2);
            pcMap.put(15L,3);
            pcMap.put(26L,2);
            pcMap.put(29L,3);
            /*Map<Long,Integer> appMap = new HashMap();
            pcMap.put(15L,4);
            pcMap.put(26L,4);
            pcMap.put(29L,4);*/
            Map<Long,Integer> permissionMap = new HashMap();
            permissionMap.put(2L,4);
            permissionMap.put(3L,7);
            permissionMap.put(4L,4);
            permissionMap.put(5L,7);
            permissionMap.put(6L,3);
            permissionMap.put(9L,2);
            permissionMap.put(10L,2);
            permissionMap.put(11L,3);
            permissionMap.put(17L,6);
            permissionMap.put(18L,6);
            permissionMap.put(19L,6);
            permissionMap.put(24L,1);
            permissionMap.put(25L,1);
            permissionMap.put(27L,1);
            permissionMap.put(28L,1);
            permissionMap.put(30L,2);
            permissionMap.put(31L,2);
            permissionMap.put(32L,1);
            modulePermissionsWithCheckedList.forEach(mpwcl -> {
                //判断第一层Module下子模块已经子模块下的权限是否全选
                List<ModulePermissionsWithChecked> mChild = mpwcl.getChildModules();
                mChild = mChild.stream().filter((mpwc) -> mpwc.isChecked() == true).collect(Collectors.toList());
                if(mChild != null  && mChild.size()< pcMap.get(mpwcl.getId())){
                    mpwcl.setChecked(false);
                }
                /*if(mChild != null && SysConstants.CHANNEL_APP.equals(mpwcl.getChannel()) && mChild.size()< appMap.get(mpwcl.getId())){
                    mpwcl.setChecked(false);
                }*/
                if(CollectionUtils.isNotEmpty(mChild)){
                    mChild.forEach(m -> {
                        List<PermissionWithChecked> lpwcl = m.getPermissionWithCheckedList().stream().filter((pwcl) -> pwcl.isChecked() == true).collect(Collectors.toList());
                        if(CollectionUtils.isNotEmpty(lpwcl) && lpwcl.size() < permissionMap.get(m.getId())){
                            mpwcl.setChecked(false);
                        }
                    });
                }
            });

            //--------------------------------------没办法的补丁end------------------------------------------------
            roleEditResponse.setModulePermissionsWithCheckeds(modulePermissionsWithCheckedList);
            rm.setData(roleEditResponse);
        }catch (Exception e){
            rm.buildSystemErrorMessage();
            logger.debug(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return rm;
    }



    public ResponseMessage<RoleEditResponse> getModulePermissionsWithCheckedForDetail(Long id) {
        ResponseMessage<RoleEditResponse> rm = new ResponseMessage<RoleEditResponse>();
        RoleEditResponse roleEditResponse =  new RoleEditResponse();
        Role role = roleDao.selectByPrimaryKey(id);
        if(role != null){
            roleEditResponse.setRole(role);
        }
        try {
            List<ModulePermissionsWithChecked> modulePermissionsWithCheckedList = this.getModuleWithChecked(0L);
            modulePermissionsWithCheckedList = getIteratModulePermissionsWithChecked(modulePermissionsWithCheckedList,id);
            //--------------------------------------没办法的补丁start------------------------------------------------
           /* Map<Long,Integer> pcMap = new HashMap();
            pcMap.put(1L,5);
            pcMap.put(7L,3);
            pcMap.put(23L,2);
            pcMap.put(15L,3);
            pcMap.put(26L,2);
            pcMap.put(29L,3);
            *//*Map<Long,Integer> appMap = new HashMap();
            pcMap.put(15L,4);
            pcMap.put(26L,4);
            pcMap.put(29L,4);*//*
            Map<Long,Integer> permissionMap = new HashMap();
            permissionMap.put(2L,4);
            permissionMap.put(3L,7);
            permissionMap.put(4L,4);
            permissionMap.put(5L,6);
            permissionMap.put(6L,3);
            permissionMap.put(9L,2);
            permissionMap.put(10L,2);
            permissionMap.put(11L,3);
            permissionMap.put(17L,6);
            permissionMap.put(18L,6);
            permissionMap.put(19L,6);
            permissionMap.put(24L,1);
            permissionMap.put(25L,1);
            permissionMap.put(27L,1);
            permissionMap.put(28L,1);
            permissionMap.put(30L,2);
            permissionMap.put(31L,2);
            permissionMap.put(32L,1);*/
            modulePermissionsWithCheckedList.forEach(mpwcl -> {
                //判断第一层Module下子模块已经子模块下的权限是否全选
                List<ModulePermissionsWithChecked> mChild = mpwcl.getChildModules();
                mChild = mChild.stream().filter((mpwc) -> mpwc.isChecked() == true).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(mChild)){
                    mpwcl.setChecked(true);
                }
            });

            //--------------------------------------没办法的补丁end------------------------------------------------
            roleEditResponse.setModulePermissionsWithCheckeds(modulePermissionsWithCheckedList);
            rm.setData(roleEditResponse);
        }catch (Exception e){
            rm.buildSystemErrorMessage();
            logger.debug(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return rm;
    }


    @Override
    public ResponseMessage<SaveOrUpdateRoleRequest> saveRoleModulePermissions(SaveOrUpdateRoleRequest saveRoleOrUpdateRequest,Long accountId) {
        ResponseMessage<SaveOrUpdateRoleRequest> rm = new ResponseMessage<SaveOrUpdateRoleRequest>();
        rm.setData(saveRoleOrUpdateRequest);
        try {

            UserAccount userAccount = userAccountDao.selectByPrimaryKey(accountId);
            //角色code不能重复
            String roleCode = saveRoleOrUpdateRequest.getRoleCode();
            Role role = new Role();
            role.setRoleCode(roleCode);
            role.setCompanyId(userAccount.getCompanyId());
            int roleTotalByCode = roleDao.queryTotalRole(role);
            if(roleTotalByCode == 0){

                if(saveRoleOrUpdateRequest !=null){
                    Role r = new Role();
                    r.setRoleCode(saveRoleOrUpdateRequest.getRoleCode());
                    r.setRoleName(saveRoleOrUpdateRequest.getRoleName());
                    r.setRoleType(saveRoleOrUpdateRequest.getRoleType());
                    r.setCreateDate(new Date());

                    if(userAccount != null && userAccount.getCompanyId() != null){
                        r.setCompanyId(userAccount.getCompanyId());
                    }
                    //新增role表，返回roleId
                    Long i = roleDao.insert(r);
                    if(i == 1l){
                        List<PkModulePermissions> pkModulePermissionsList = saveRoleOrUpdateRequest.getPkModulePermissionsList();
                        if(CollectionUtils.isNotEmpty(pkModulePermissionsList)){

                            //拿出所有的moduleId
                            List<Long> cModuleIds = pkModulePermissionsList.stream().map(PkModulePermissions::getModuleId).collect(Collectors.toList());
                            //通过所有moduleIds查询对应父节点Id，排除父节点Id为0的，和子模块id比较，如果子模块Id中没有的，加入
                            List<Long> pModuleIds = moduleDao.selectParentIdByModuleId(cModuleIds).stream().distinct().collect(Collectors.toList());
                            pModuleIds.forEach(p -> {
                                if(p>0 && !cModuleIds.contains(p)){
                                    PkModulePermissions pkModulePermissions = new PkModulePermissions();
                                    pkModulePermissions.setModuleId(p);
                                    List<Long> viewP = new ArrayList<Long>(1);
                                    viewP.add(2L);
                                    pkModulePermissions.setPermissionIds(viewP);
                                    pkModulePermissionsList.add(pkModulePermissions);
                                }
                            });
                            //前台不传的主模块ID，后台获取


                            List<RoleModulePermission> insertData = new ArrayList<RoleModulePermission>();
                            pkModulePermissionsList.forEach(pkModulePermissions -> {
                                Long moduleId = pkModulePermissions.getModuleId();

                                List<Long> permissionIds = pkModulePermissions.getPermissionIds();
                                permissionIds.forEach(l -> {
                                    RoleModulePermission rmp = new RoleModulePermission();
                                    rmp.setRoleId(r.getId());
                                    rmp.setModuleId(moduleId);
                                    rmp.setPermissionId(l);
                                    rmp.setCreateDate(new Date());
                                    insertData.add(rmp);
                                    //新增role_module_permission表
                                    //roleModulePermissionDao.insert(rmp);
                                });
                            });
                            //批量新增
                            roleModulePermissionDao.batchInsert(insertData);
                        }
                    }
                }else{
                    rm.buildParamErrorMessage();
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }
            }else{
                rm.buildRoleCodeRepeatMessage();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return rm;
            }
        }catch (Exception e){
            rm.buildSystemErrorMessage();
            logger.debug(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return rm;
        }
        return rm;
    }

    @Override
    public ResponseMessage<SaveOrUpdateRoleRequest> saveOrUpdateRoleModulePermissions(SaveOrUpdateRoleRequest saveRoleOrUpdateRequest,Long accountId) {
        ResponseMessage<SaveOrUpdateRoleRequest> rm = new ResponseMessage<SaveOrUpdateRoleRequest>();
        if(saveRoleOrUpdateRequest!=null && saveRoleOrUpdateRequest.getRoleId()!=null && saveRoleOrUpdateRequest.getRoleId() > 0){
            //update
            rm = this.updateRoleModulePermissions(saveRoleOrUpdateRequest,accountId);
        }else{
            //insert
            rm = this.saveRoleModulePermissions(saveRoleOrUpdateRequest,accountId);
        }
        return rm;
    }

    @Override
    public ResponseMessage<SaveOrUpdateRoleRequest> updateRoleModulePermissions(SaveOrUpdateRoleRequest saveRoleOrUpdateRequest,Long accountId) {
        ResponseMessage<SaveOrUpdateRoleRequest> rm = new ResponseMessage<SaveOrUpdateRoleRequest>();
        rm.setData(saveRoleOrUpdateRequest);
        try {

            UserAccount userAccount = userAccountDao.selectByPrimaryKey(accountId);
            if(saveRoleOrUpdateRequest !=null && saveRoleOrUpdateRequest.getRoleId() != null){

                String roleCode = saveRoleOrUpdateRequest.getRoleCode();
                Long roleId = saveRoleOrUpdateRequest.getRoleId();
                Role role = new Role();
                role.setId(roleId);
                role.setRoleCode(roleCode);
                role.setCompanyId(userAccount.getCompanyId());
                int roleTotalByCode = roleDao.queryTotalRoleForUpdate(role);

                if(roleTotalByCode == 0){
                    Role r = new Role();
                    r.setId(saveRoleOrUpdateRequest.getRoleId());
                    r.setRoleCode(saveRoleOrUpdateRequest.getRoleCode());
                    r.setRoleName(saveRoleOrUpdateRequest.getRoleName());
                    r.setRoleType(saveRoleOrUpdateRequest.getRoleType());
                    r.setCreateDate(new Date());
                    //修改role表
                    roleDao.updateByPrimaryKey(r);
                    //逻辑删除role_module_permission表中此role_id的数据，表seal_mark改为1
                    roleModulePermissionDao.deleteByRoleKey(saveRoleOrUpdateRequest.getRoleId());
                    //新增role_module_permission表
                    List<RoleModulePermission> insertData = new ArrayList<RoleModulePermission>();
                    List<PkModulePermissions> pkModulePermissionsList = saveRoleOrUpdateRequest.getPkModulePermissionsList();
                    if(CollectionUtils.isNotEmpty(pkModulePermissionsList)){

                    //拿出所有的moduleId
                    List<Long> cModuleIds = pkModulePermissionsList.stream().map(PkModulePermissions::getModuleId).collect(Collectors.toList());
                    //通过所有moduleIds查询对应父节点Id，排除父节点Id为0的，和子模块id比较，如果子模块Id中没有的，加入
                    List<Long> pModuleIds = moduleDao.selectParentIdByModuleId(cModuleIds).stream().distinct().collect(Collectors.toList());
                    pModuleIds.forEach(p -> {
                        if(!cModuleIds.contains(p)){
                            PkModulePermissions pkModulePermissions = new PkModulePermissions();
                            pkModulePermissions.setModuleId(p);
                            List<Long> viewP = new ArrayList<Long>(1);
                            viewP.add(2L);
                            pkModulePermissions.setPermissionIds(viewP);
                            pkModulePermissionsList.add(pkModulePermissions);
                        }
                    });
                    //前台不传的主模块ID，后台获取


                    pkModulePermissionsList.forEach(pkModulePermissions -> {
                        Long moduleId = pkModulePermissions.getModuleId();
                        List<Long> permissionIds = pkModulePermissions.getPermissionIds();
                        permissionIds.forEach(l -> {
                            RoleModulePermission rmp = new RoleModulePermission();
                            rmp.setRoleId(saveRoleOrUpdateRequest.getRoleId());
                            rmp.setModuleId(moduleId);
                            rmp.setPermissionId(l);
                            rmp.setCreateDate(new Date());
                            //roleModulePermissionDao.insert(rmp);
                            insertData.add(rmp);
                        });
                    });
                    roleModulePermissionDao.batchInsert(insertData);
                    }

                    //修改角色完成，查询所有带有此角色的用户，全部踢下线
                    this.clearUserSessionWhenRoleChanged(roleId);
                }else{
                    rm.buildRoleCodeRepeatMessage();
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }




                //角色修改，所有由此角色的用户登录状态全部踢掉
                /*this.clearUserSessionWhenRoleChanged(saveRoleOrUpdateRequest.getRoleId());*/
            }else{
                rm.buildParamErrorMessage();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }catch (Exception e){
            rm.buildSystemErrorMessage();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
            return rm;
        }

        return rm;
    }

    @Override
    public ResponseMessage<Long> deleteRole(Long id) {
        ResponseMessage<Long> rm = new ResponseMessage<Long>();
        rm.setData(id);
        try {
            roleDao.deleteByPrimaryKey(id);
            roleModulePermissionDao.deleteByRoleKey(id);
            accountRoleDao.deleteByRoleId(id);
            userRoleDao.updateSealMarkByRoleId(id);

            this.clearUserSessionWhenRoleChanged(id);
        }catch (Exception e){
            rm.buildExecuteFailMessage();
            logger.debug(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return rm;
    }

    @Override
    public ResponseMessage<Long> updateEnableMark(int enableMark,Long id) {
        ResponseMessage<Long> rm = new ResponseMessage<Long>();
        try {
            roleDao.updateEnableMark(enableMark,id);
            roleModulePermissionDao.updateEnableMarkByRoleId(id,enableMark);
            accountRoleDao.updateEnableMarkByRoleId(id,enableMark);
            userRoleDao.updateEnableMarkByRoleId(id,enableMark);

            rm.setData(id);
            this.clearUserSessionWhenRoleChanged(id);
        }catch (Exception e){
            rm.buildSystemErrorMessage();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
        }
        return rm;
    }

    @Override
    public ResponseMessage<RoleDetail> queryRoleDetail(Long id) {
        ResponseMessage<RoleDetail> rm = new ResponseMessage<RoleDetail>();
        RoleDetail roleDetail = new RoleDetail();
        try {

            Role role = roleDao.selectByPrimaryKey(id);
            if(role != null){
            RoleWithRoleType roleWithRoleType = new RoleWithRoleType();
            BeanUtils.copyProperties(role,roleWithRoleType);
                if(roleWithRoleType.getRoleType() == RoleTypeEnum.ROLE_TYPE_FORMAL.getKey()){
                    roleWithRoleType.setRoleTypeName(RoleTypeEnum.ROLE_TYPE_FORMAL.getValue());
                }else if(roleWithRoleType.getRoleType() == RoleTypeEnum.ROLE_TYPE_TEMPLATE.getKey()){
                    roleWithRoleType.setRoleTypeName(RoleTypeEnum.ROLE_TYPE_TEMPLATE.getValue());
                }
                roleDetail.setRoleWithRoleType(roleWithRoleType);

                ResponseMessage<RoleEditResponse> data= this.getModulePermissionsWithCheckedForDetail(id);
                if(data != null){
                    RoleEditResponse roleEditResponse = data.getData();
                    if(roleEditResponse != null){
                        roleDetail.setModulePermissionsWithCheckeds(roleEditResponse.getModulePermissionsWithCheckeds());
                        roleDetail.setRole(roleEditResponse.getRole());
                    }
                    rm.setInfo(data.getInfo());
                    rm.setDescription(data.getDescription());
                    rm.setMessageCode(data.getMessageCode());
                    rm.setSuccess(data.isSuccess());
                }

                Map<Integer,String> map = new HashMap<Integer,String>();
                map.put(RoleTypeEnum.ROLE_TYPE_FORMAL.getKey(),RoleTypeEnum.ROLE_TYPE_FORMAL.getValue());
                map.put(RoleTypeEnum.ROLE_TYPE_TEMPLATE.getKey(),RoleTypeEnum.ROLE_TYPE_TEMPLATE.getValue());
                roleDetail.setRoleTypeMap(map);
            }
            rm.setData(roleDetail);
        }catch (Exception e){
            rm.buildSystemErrorMessage();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
        }

        return rm;
    }

    @Override
    public ResponseMessage<RoleInsertInfo> queryRoleInsertInfo() {
        ResponseMessage<RoleInsertInfo> rm = new ResponseMessage<RoleInsertInfo>();
        RoleInsertInfo roleInsertInfo = new RoleInsertInfo();
        try {
            ResponseMessage<List<ModulePermissions>> data = this.getModulePermissions();
            if(data != null){
                List<ModulePermissions> modulePermissionses = data.getData();
                if(modulePermissionses != null){
                    roleInsertInfo.setModulePermissionses(modulePermissionses);
                }
                rm.setInfo(data.getInfo());
                rm.setDescription(data.getDescription());
                rm.setMessageCode(data.getMessageCode());
                rm.setSuccess(data.isSuccess());
            }

            Map<Integer,String> map = new HashMap<Integer,String>();
            map.put(RoleTypeEnum.ROLE_TYPE_FORMAL.getKey(),RoleTypeEnum.ROLE_TYPE_FORMAL.getValue());
            map.put(RoleTypeEnum.ROLE_TYPE_TEMPLATE.getKey(),RoleTypeEnum.ROLE_TYPE_TEMPLATE.getValue());
            roleInsertInfo.setRoleTypeMap(map);

            rm.setData(roleInsertInfo);
        }catch (Exception e){
            rm.buildSystemErrorMessage();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
        }

        return rm;
    }

    @Override
    public ResponseMessage<Long> copyRole(Long id) {
        ResponseMessage<Long> rm = new ResponseMessage<Long>();
        try {
            Role sourceRole = roleDao.selectByPrimaryKey(id);
            Role targetRole = new Role();
            if(sourceRole != null){
                BeanUtils.copyProperties(sourceRole,targetRole);
                targetRole.setId(null);
                targetRole.setRoleCode(sourceRole.getRoleCode()+"-1");
                targetRole.setCreateDate(new Date());
                targetRole.setModifyDate(null);
            }
            roleDao.insert(targetRole);
            List<RoleModulePermission> roleModulePermissions = roleModulePermissionDao.selectByRoleKey(id);
            if(CollectionUtils.isNotEmpty(roleModulePermissions)){
                roleModulePermissions.forEach(r -> {
                    r.setId(null);
                    r.setRoleId(targetRole.getId());
                    r.setCreateDate(new Date());
                });

                roleModulePermissionDao.batchInsert(roleModulePermissions);
            }
            rm.setData(targetRole.getId());
        }catch (Exception e){
            rm.buildSystemErrorMessage();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
        }

        return rm;
    }

    @Override
    public ResponseMessage<PcLoginDataResponse> getPcLoginData(String username, String channel) {
        PcLoginDataResponse pcLoginDataResponse = new PcLoginDataResponse();
        ResponseMessage<PcLoginDataResponse> rm = new ResponseMessage<PcLoginDataResponse>();
        try{
            /*UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext()
                    .getAuthentication()
                    .getPrincipal();

            //查询当前登录用户
            String username = userDetails.getUsername();*/
            //根据用户名查询用户账号
            UserAccount userAccount = userAccountDao.selectByUsername(username);
            Long userId = userAccount.getUserId();
            User user = userDao.selectById(userId);
            pcLoginDataResponse.setUsername(user.getUserName());
            //pcLoginDataResponse.setUsername(username);

            //根据账号Id查询对应角色
            List<AccountRole> accountRoles = accountRoleDao.selectByUserAccountKey(userAccount.getId());
            List<Long> roleIds = accountRoles.stream().map(AccountRole :: getRoleId).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(roleIds)){
                //根据角色Id列表查询对应的module和permission
                List<ModulePermissionByRoles> roleModulePermissions = roleModulePermissionDao.selectLoginInfoByRolesKey(roleIds,channel);
                if(CollectionUtils.isNotEmpty(roleModulePermissions)){
                    List<Long> modules = roleModulePermissions.stream().map(ModulePermissionByRoles::getModuleId).collect(Collectors.toList());
                    Map<Long,List<Long>> modulePermissions = new HashMap<Long,List<Long>>();
                    modulePermissions = roleModulePermissions.stream().collect(Collectors.groupingBy(i -> i.getModuleId(),Collectors.mapping(i -> i.getPermissionId(),Collectors.toList())));

            /*//角色对应moduleId列表,因同一个用户有多个角色，所以会出现重复module的情况，去重；
            List<Long> modules = roleModulePermissions.stream().map(RoleModulePermission :: getModuleId).distinct().collect(Collectors.toList());
            //按照moduleId分组
            Map<Long,List<RoleModulePermission>> maps = roleModulePermissions.stream().collect(Collectors.groupingBy(i -> i.getModuleId()));
            Map<Long,List<Long>> modulePermissions = new HashMap<Long,List<Long>>();
            maps.forEach((k,v) -> {
                //因一个用户对应多个角色，所以产生相同module中，permission重复的情况，去除重复permission
                List<Long> permissions = v.stream().map(RoleModulePermission :: getPermissionId).distinct().collect(Collectors.toList());
                List<Long> distinctedPermissions = permissions.stream().distinct().collect(Collectors.toList());
                modulePermissions.put(k,distinctedPermissions);
            });*/
                    //根据moduleIds，取出每一层的module
                    List<ModulePermissions> firstLevelModules = moduleDao.selectByModuleKeys(modules,0L);
                    List<ModulePermissions> modulePermissionsesList = this.getIteratModulePermissionsByModuleIds(firstLevelModules,modules,modulePermissions);
                    pcLoginDataResponse.setLeftMenuData(modulePermissionsesList);
                    rm.setData(pcLoginDataResponse);
                }
                /*else{
                    //角色在这个channel没有对应模块
                    rm.buildParamErrorMessage();
                    //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return rm;
                }*/
            }else{
                rm.buildNoRoleLoginFalseMessage();
                return rm;
            }

        }catch (Exception e){
            rm.buildSystemErrorMessage();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
        }
        return rm;
    }

    private List<ModulePermissions> getIteratModulePermissionsByModuleIds(List<ModulePermissions> modulePermissionses,List<Long> moduleIds,Map<Long,List<Long>> modulePermissionKeys){
        try {
            if(modulePermissionses != null && modulePermissionses.size() > 0){
                modulePermissionses.forEach(modulePermission -> {
                    //moduleId作为查询子模块时的parentId
                    Long parentId = modulePermission.getId();

                    if(modulePermissionKeys.containsKey(parentId)){
                        List<Long> permissionIds = modulePermissionKeys.get(parentId);
                        //通过permission主键列表查询对应Permission对象列表
                        List<Permission> permissions = permissionDao.selectByPermissionKeys(permissionIds);
                        //List<String> permissionsCode = modulePermissionKeys.get(parentId);
                        modulePermission.setPermissionList(permissions);
                    }

                    //查询是否有子模块
                    List<ModulePermissions> childModules = moduleDao.selectByModuleKeys(moduleIds,parentId);
                    if(childModules != null && childModules.size() > 0){
                        //存在子模块，set，并且子模块list继续迭代
                        modulePermission.setChildModules(childModules);
                        this.getIteratModulePermissionsByModuleIds(childModules,moduleIds,modulePermissionKeys);
                    }
                });
            }
            return modulePermissionses;
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
            return null;
        }

    }

    @Override
    public ResponseMessage<LoginDataResponse> getAppLoginData(String username,String channel) {
        ResponseMessage<LoginDataResponse> rm = new ResponseMessage<LoginDataResponse>();
        try{
            LoginDataResponse loginDataResponse = new LoginDataResponse();
            List<ModulePermissionLoginData> modulePermissionLoginDatas = new ArrayList<ModulePermissionLoginData>();

            Long accountId = 0L;
            //根据用户名查询用户账号
            if(SysConstants.CHANNEL_PAD.equals(channel)){
                ShopAccount shopAccount = shopAccountDao.selectByUsername(username);
                if(shopAccount == null){
                    rm.buildParamErrorMessage();
                    return rm;
                }else{
                    accountId = shopAccount.getId();
                    List<ShopAccountModule> shopAccountModules = shopAccountModuleDao.selectShopAccountModuleList(accountId);
                    if(CollectionUtils.isNotEmpty(shopAccountModules)){
                        List<Long> moduleIds = shopAccountModules.stream().map(ShopAccountModule::getModuleId).collect(Collectors.toList());
                        if(CollectionUtils.isNotEmpty(moduleIds)){
                            List<Module> modules = moduleDao.selectByKeys(moduleIds);
                            modules.forEach(module -> {
                                ModulePermissionLoginData modulePermissionLoginData = new ModulePermissionLoginData();
                                modulePermissionLoginData.setCode(module.getModuleCode());
                                modulePermissionLoginData.setName(module.getModuleName());
                                modulePermissionLoginDatas.add(modulePermissionLoginData);
                            });
                            loginDataResponse.setModules(modulePermissionLoginDatas);
                            rm.setData(loginDataResponse);
                        }
                    }
                    }
            }else {
                UserAccount userAccount = userAccountDao.selectByUsername(username);
                if (userAccount == null) {
                    rm.buildParamErrorMessage();
                    return rm;
                } else {
                    accountId = userAccount.getId();
                    if(accountId > 0){
                        //根据账号Id查询对应角色
                        List<AccountRole> accountRoles = accountRoleDao.selectByUserAccountKey(accountId);
                        List<Long> roleIds = accountRoles.stream().map(AccountRole :: getRoleId).collect(Collectors.toList());
                        if(CollectionUtils.isEmpty(roleIds)){
                            rm.buildNoRoleLoginFalseMessage();
                            return rm;
                        }
                        List<ModulePermissionByRoles> modulePermissionByRoles = roleModulePermissionDao.selectLoginInfoByRolesKey(roleIds,channel);

                        Map<String,List<ModulePermissionByRoles>> map = modulePermissionByRoles.stream().collect(Collectors.groupingBy(i -> i.getModuleCode()));
                        map.forEach((k,v) -> {
                            ModulePermissionLoginData modulePermissionLoginData = new ModulePermissionLoginData();
                            modulePermissionLoginData.setCode(k);
                            modulePermissionLoginData.setName(v.get(0).getModuleName());
                            List<String> permissions = v.stream().map(ModulePermissionByRoles :: getPermissionCode).collect(Collectors.toList());
                            modulePermissionLoginData.setPermissions(permissions);
                            modulePermissionLoginDatas.add(modulePermissionLoginData);
                        });
                        loginDataResponse.setModules(modulePermissionLoginDatas);
                    }
                    rm.setData(loginDataResponse);
                }
            }
            /*UserAccount userAccount = userAccountDao.selectByUsername(username);
            if(userAccount != null){
                //查询账号对应的APP所有主模块ID
                accountId = userAccount.getId();

            }else{
                rm.buildParamErrorMessage();
                return rm;
            }*/


        }catch (Exception e){
            rm.buildSystemErrorMessage();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.debug(e.getMessage(), e);
        }

        return rm;
    }

    private void clearUserSessionWhenRoleChanged(Long roleId){
        List<String> usernames = accountRoleDao.selectAccountNameByRoleId(roleId);
        if(CollectionUtils.isNotEmpty(usernames)){
            SessionUtil.batchInvalidateSession(sessionRepository,usernames);
        }
    }
}
